#include <omnetpp.h>

/*
 * Functions implemented
 */

static double probs[4] = { 0.3017, 0.4244, 0.5552, 1.0 };	// CDF
static double sizes[4] = { 48, 4096, 4288, 11680 };	// Sizes according to CDF

double lt3_multimodal(double remainingSize, double rngId) {
	// Get the larger packet size according to the currentLength
	int i = 3;
	while (sizes[i] > (unsigned long)remainingSize && i > 0) i--;
	
	// Uniform according to the packet sizes available
	double p = uniform(0, probs[i], rngId);
	  
	// Get the size according to the probability generated
	i = 0;
	while (probs[i] < p && i < 3) i++;
	return sizes[i];
}

double lt3_transparent(double remainingSize) {
	return remainingSize;
}

double lt3_rng(double vmin,double vmax, double rngId) {
	// OMNeT++ statistic function --> uniform distribution in [vmin, vmax)
	return uniform(vmin,vmax, (int) rngId);
}

double lt3_seeds(double gap, double vmin, double vmax, double rngId) {

	for (unsigned long i = 0; i < (unsigned long) gap; i++) uniform(vmin, vmax, rngId);
	return uniform(vmin, vmax, rngId);
}

// -----------------------------------------------------------------------------------
/*
 * Funtions to be implemented
 */

double lt3_exponential(double mean, double rngId) {
	// TODO
	return 0;
}

double lt3_geometric(double vmin, double vmax, double mean, double rngId) {
	// Geometric variable with minimum value "vmin",
	// maximum value "vmax", using an exponetial variable with mean as the first moment
	// TODO
	return 0;
}


double lt3_normal(double mean, double variance, double method, double rngId) {
	// Normal variable generation with diferent methods
	// TODO
	return 0;
}

double lt3_exponential_convolution(double mean, double numExp, double rngId) {
	// Variable T generation (exercise 6)
	// mean is the first moment of each exponential variable used
	// numExp is the number of exponential variables
	// TODO
	return 0;
}

double lt3_chi2(double k, double rngId) {
	// k degrees of freedom
	// TODO
	return 0;
}

// Registering functions in OMNeT
Define_Function(lt3_multimodal, 2);
Define_Function(lt3_transparent, 1);
Define_Function(lt3_rng, 3);
Define_Function(lt3_seeds,4);
Define_Function(lt3_exponential, 2);
Define_Function(lt3_geometric, 4);
Define_Function(lt3_normal, 4);
Define_Function(lt3_exponential_convolution, 3);
Define_Function(lt3_chi2, 2);
